home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / lwings.c < prev    next >
C/C++ Source or Header  |  2000-05-04  |  14KB  |  517 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7. ***************************************************************************/
  8.  
  9. #include "driver.h"
  10. #include "vidhrdw/generic.h"
  11.  
  12. #include "osdepend.h"
  13.  
  14. static int trojan_vh_type;
  15. unsigned char *lwings_backgroundram;
  16. unsigned char *lwings_backgroundattribram;
  17. size_t lwings_backgroundram_size;
  18. unsigned char *lwings_scrolly;
  19. unsigned char *lwings_scrollx;
  20.  
  21. unsigned char *trojan_scrolly;
  22. unsigned char *trojan_scrollx;
  23. unsigned char *trojan_bk_scrolly;
  24. unsigned char *trojan_bk_scrollx;
  25.  
  26. static unsigned char *dirtybuffer2;
  27. static unsigned char *dirtybuffer4;
  28. static struct osd_bitmap *tmpbitmap2;
  29. static struct osd_bitmap *tmpbitmap3;
  30.  
  31.  
  32.  
  33. /***************************************************************************
  34.  
  35.   Start the video hardware emulation.
  36.  
  37. ***************************************************************************/
  38. int lwings_vh_start(void)
  39. {
  40.     int i;
  41.  
  42.  
  43.     if (generic_vh_start() != 0)
  44.         return 1;
  45.  
  46.         if ((dirtybuffer2 = malloc(lwings_backgroundram_size)) == 0)
  47.     {
  48.         generic_vh_stop();
  49.         return 1;
  50.     }
  51.         memset(dirtybuffer2,1,lwings_backgroundram_size);
  52.  
  53.         if ((dirtybuffer4 = malloc(lwings_backgroundram_size)) == 0)
  54.     {
  55.         generic_vh_stop();
  56.         return 1;
  57.     }
  58.         memset(dirtybuffer4,1,lwings_backgroundram_size);
  59.  
  60.     /* the background area is twice as tall as the screen */
  61.         if ((tmpbitmap2 = osd_new_bitmap(2*Machine->drv->screen_width,
  62.                 2*Machine->drv->screen_height,Machine->scrbitmap->depth)) == 0)
  63.     {
  64.         free(dirtybuffer2);
  65.         generic_vh_stop();
  66.         return 1;
  67.     }
  68.  
  69.  
  70. #define COLORTABLE_START(gfxn,color_code) Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + \
  71.                 color_code * Machine->gfx[gfxn]->color_granularity
  72. #define GFX_COLOR_CODES(gfxn) Machine->gfx[gfxn]->total_colors
  73. #define GFX_ELEM_COLORS(gfxn) Machine->gfx[gfxn]->color_granularity
  74.  
  75.     palette_init_used_colors();
  76.     /* chars */
  77.     for (i = 0;i < GFX_COLOR_CODES(0);i++)
  78.     {
  79.         memset(&palette_used_colors[COLORTABLE_START(0,i)],
  80.                 PALETTE_COLOR_USED,
  81.                 GFX_ELEM_COLORS(0));
  82.         palette_used_colors[COLORTABLE_START(0,i) + GFX_ELEM_COLORS(0)-1] = PALETTE_COLOR_TRANSPARENT;
  83.     }
  84.     /* bg tiles */
  85.     for (i = 0;i < GFX_COLOR_CODES(1);i++)
  86.     {
  87.         memset(&palette_used_colors[COLORTABLE_START(1,i)],
  88.                 PALETTE_COLOR_USED,
  89.                 GFX_ELEM_COLORS(1));
  90.     }
  91.     /* sprites */
  92.     for (i = 0;i < GFX_COLOR_CODES(2);i++)
  93.     {
  94.         memset(&palette_used_colors[COLORTABLE_START(2,i)],
  95.                 PALETTE_COLOR_USED,
  96.                 GFX_ELEM_COLORS(2));
  97.     }
  98.  
  99.     return 0;
  100. }
  101.  
  102. /***************************************************************************
  103.  
  104.   Stop the video hardware emulation.
  105.  
  106. ***************************************************************************/
  107. void lwings_vh_stop(void)
  108. {
  109.     osd_free_bitmap(tmpbitmap2);
  110.     free(dirtybuffer2);
  111.     free(dirtybuffer4);
  112.     generic_vh_stop();
  113. }
  114.  
  115. WRITE_HANDLER( lwings_background_w )
  116. {
  117.     if (lwings_backgroundram[offset] != data)
  118.     {
  119.         lwings_backgroundram[offset] = data;
  120.         dirtybuffer2[offset] = 1;
  121.     }
  122. }
  123.  
  124. WRITE_HANDLER( lwings_backgroundattrib_w )
  125. {
  126.     if (lwings_backgroundattribram[offset] != data)
  127.     {
  128.         lwings_backgroundattribram[offset] = data;
  129.         dirtybuffer4[offset] = 1;
  130.     }
  131. }
  132.  
  133.  
  134.  
  135. /***************************************************************************
  136.  
  137.   Draw the game screen in the given osd_bitmap.
  138.   Do NOT call osd_update_display() from this function, it will be called by
  139.   the main emulation engine.
  140.  
  141. ***************************************************************************/
  142.  
  143. void lwings_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  144. {
  145.     int offs;
  146.  
  147.  
  148.     if (palette_recalc())
  149.     {
  150.         memset(dirtybuffer2,1,lwings_backgroundram_size);
  151.         memset(dirtybuffer4,1,lwings_backgroundram_size);
  152.     }
  153.  
  154.  
  155.     for (offs = lwings_backgroundram_size - 1;offs >= 0;offs--)
  156.     {
  157.         int sx,sy, colour;
  158.         /*
  159.         Tiles
  160.         =====
  161.         0x80 Tile code MSB
  162.         0x40 Tile code MSB
  163.         0x20 Tile code MSB
  164.         0x10 X flip
  165.         0x08 Y flip
  166.         0x04 Colour
  167.         0x02 Colour
  168.         0x01 Colour
  169.         */
  170.  
  171.         colour=(lwings_backgroundattribram[offs] & 0x07);
  172.         if (dirtybuffer2[offs] != 0 || dirtybuffer4[offs] != 0)
  173.         {
  174.             int code;
  175.             dirtybuffer2[offs] = dirtybuffer4[offs] = 0;
  176.  
  177.             sx = offs / 32;
  178.             sy = offs % 32;
  179.             code=lwings_backgroundram[offs];
  180.             code+=((((int)lwings_backgroundattribram[offs]) &0xe0) <<3);
  181.  
  182.             drawgfx(tmpbitmap2,Machine->gfx[1],
  183.                     code,
  184.                     colour,
  185.                     (lwings_backgroundattribram[offs] & 0x08),
  186.                     (lwings_backgroundattribram[offs] & 0x10),
  187.                     16 * sx,16 * sy,
  188.                     0,TRANSPARENCY_NONE,0);
  189.         }
  190.     }
  191.  
  192.  
  193.     /* copy the background graphics */
  194.     {
  195.         int scrollx,scrolly;
  196.  
  197.  
  198.         scrolly = -(lwings_scrollx[0] + 256 * lwings_scrollx[1]);
  199.         scrollx = -(lwings_scrolly[0] + 256 * lwings_scrolly[1]);
  200.  
  201.         copyscrollbitmap(bitmap,tmpbitmap2,1,&scrollx,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  202.     }
  203.  
  204.  
  205.     /* Draw the sprites. */
  206.     for (offs = spriteram_size - 4;offs >= 0;offs -= 4)
  207.     {
  208.         int code,sx,sy;
  209.  
  210.         /*
  211.         Sprites
  212.         =======
  213.         0x80 Sprite code MSB
  214.         0x40 Sprite code MSB
  215.         0x20 Colour
  216.         0x10 Colour
  217.         0x08 Colour
  218.         0x04 Y flip
  219.         0x02 X flip
  220.         0x01 X MSB
  221.         */
  222.         sx = spriteram[offs + 3] - 0x100 * (spriteram[offs + 1] & 0x01);
  223.         sy = spriteram[offs + 2];
  224.         if (sx && sy)
  225.         {
  226.             code = spriteram[offs];
  227.             code += (spriteram[offs + 1] & 0xc0) << 2;
  228.  
  229.             drawgfx(bitmap,Machine->gfx[2],
  230.                     code,
  231.                     (spriteram[offs + 1] & 0x38) >> 3,
  232.                     spriteram[offs + 1] & 0x02,spriteram[offs + 1] & 0x04,
  233.                     sx,sy,
  234.                     &Machine->drv->visible_area,TRANSPARENCY_PEN,15);
  235.         }
  236.     }
  237.  
  238.     /* draw the frontmost playfield. They are characters, but draw them as sprites */
  239.     for (offs = videoram_size - 1;offs >= 0;offs--)
  240.     {
  241.         int sx,sy;
  242.  
  243.  
  244.         sx = offs % 32;
  245.         sy = offs / 32;
  246.  
  247.         drawgfx(bitmap,Machine->gfx[0],
  248.                 videoram[offs] + 4 * (colorram[offs] & 0xc0),
  249.                 colorram[offs] & 0x0f,
  250.                 colorram[offs] & 0x10,colorram[offs] & 0x20,
  251.                 8*sx,8*sy,
  252.                 &Machine->drv->visible_area,TRANSPARENCY_PEN,3);
  253.     }
  254. }
  255.  
  256. /*
  257. TROJAN
  258. ======
  259.  
  260. Differences:
  261.  
  262. Tile attribute (no y flip, possible priority)
  263. Sprite attribute (more sprites)
  264. Extra scroll layer
  265.  
  266. */
  267.  
  268. int  trojan_vh_start(void)
  269. {
  270.     int i;
  271.     trojan_vh_type = 0;
  272.  
  273.     if (generic_vh_start() != 0)
  274.         return 1;
  275.  
  276.         if ((dirtybuffer2 = malloc(lwings_backgroundram_size)) == 0)
  277.     {
  278.         generic_vh_stop();
  279.         return 1;
  280.     }
  281.         memset(dirtybuffer2,1,lwings_backgroundram_size);
  282.  
  283.  
  284.         if ((dirtybuffer4 = malloc(lwings_backgroundram_size)) == 0)
  285.     {
  286.         generic_vh_stop();
  287.         return 1;
  288.     }
  289.         memset(dirtybuffer4,1,lwings_backgroundram_size);
  290.  
  291.         if ((tmpbitmap3 = osd_new_bitmap(16*0x12,
  292.                 16*0x12,Machine->scrbitmap->depth)) == 0)
  293.         {
  294.         free(dirtybuffer4);
  295.         free(dirtybuffer2);
  296.         generic_vh_stop();
  297.         return 1;
  298.  
  299.         }
  300.  
  301.  
  302. #define COLORTABLE_START(gfxn,color_code) Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + \
  303.                 color_code * Machine->gfx[gfxn]->color_granularity
  304. #define GFX_COLOR_CODES(gfxn) Machine->gfx[gfxn]->total_colors
  305. #define GFX_ELEM_COLORS(gfxn) Machine->gfx[gfxn]->color_granularity
  306.  
  307.     palette_init_used_colors();
  308.     /* chars */
  309.     for (i = 0;i < GFX_COLOR_CODES(0);i++)
  310.     {
  311.         memset(&palette_used_colors[COLORTABLE_START(0,i)],
  312.                 PALETTE_COLOR_USED,
  313.                 GFX_ELEM_COLORS(0));
  314.         palette_used_colors[COLORTABLE_START(0,i) + GFX_ELEM_COLORS(0)-1] = PALETTE_COLOR_TRANSPARENT;
  315.     }
  316.     /* fg tiles */
  317.     for (i = 0;i < GFX_COLOR_CODES(1);i++)
  318.     {
  319.         memset(&palette_used_colors[COLORTABLE_START(1,i)],
  320.                 PALETTE_COLOR_USED,
  321.                 GFX_ELEM_COLORS(1));
  322.     }
  323.     /* sprites */
  324.     for (i = 0;i < GFX_COLOR_CODES(2);i++)
  325.     {
  326.         memset(&palette_used_colors[COLORTABLE_START(2,i)],
  327.                 PALETTE_COLOR_USED,
  328.                 GFX_ELEM_COLORS(2));
  329.     }
  330.     /* bg tiles */
  331.     for (i = 0;i < GFX_COLOR_CODES(3);i++)
  332.     {
  333.         memset(&palette_used_colors[COLORTABLE_START(3,i)],
  334.                 PALETTE_COLOR_USED,
  335.                 GFX_ELEM_COLORS(3));
  336.     }
  337.  
  338.     return 0;
  339. }
  340.  
  341. int avengers_vh_start( void ){
  342.     int result = trojan_vh_start();
  343.     trojan_vh_type = 1;
  344.     return result;
  345. }
  346.  
  347. void trojan_vh_stop(void)
  348. {
  349.         osd_free_bitmap(tmpbitmap3);
  350.         free(dirtybuffer4);
  351.         free(dirtybuffer2);
  352.         generic_vh_stop();
  353. }
  354.  
  355. void trojan_render_foreground( struct osd_bitmap *bitmap, int scrollx, int scrolly, int priority )
  356. {
  357.         int scrlx = -(scrollx&0x0f);
  358.         int scrly = -(scrolly&0x0f);
  359.         int sx, sy;
  360.         int offsy = (scrolly >> 4)-1;
  361.         int offsx = (scrollx >> 4)*32-32;
  362.  
  363.         int transp0,transp1;
  364.         if( priority ){
  365.         transp0 = 0xFFFF;    /* draw nothing (all pens transparent) */
  366.         transp1 = 0xF00F;    /* high priority half of tile */
  367.     }
  368.         else {
  369.         transp0 = 1;        /* TRANSPARENCY_PEN, color 0 */
  370.         transp1 = 0x0FF0;    /* low priority half of tile */
  371.     }
  372.  
  373.         for (sx=0; sx<0x12; sx++)
  374.         {
  375.                 offsx&=0x03ff;
  376.                 for (sy=0; sy<0x12; sy++)
  377.                 {
  378.                 /*
  379.                         Tiles
  380.                         0x80 Tile code MSB
  381.                         0x40 Tile code MSB
  382.                         0x20 Tile code MSB
  383.                         0x10 X flip
  384.                         0x08 Priority ????
  385.                         0x04 Colour
  386.                         0x02 Colour
  387.                         0x01 Colour
  388.                */
  389.                        int offset = offsx+( (sy+offsy)&0x1f );
  390.                        int attribute = lwings_backgroundattribram[offset];
  391.                        drawgfx(bitmap,Machine->gfx[1],
  392.                                 lwings_backgroundram[offset] + ((attribute &0xe0) <<3),
  393.                                 attribute & 0x07,
  394.                                 attribute & 0x10,
  395.                                 0,
  396.                                 16 * sx+scrlx-16,16 * sy+scrly-16, &Machine->drv->visible_area, TRANSPARENCY_PENS,(attribute & 0x08)?transp1:transp0 );
  397.                 }
  398.                 offsx+=0x20;
  399.     }
  400. }
  401.  
  402. static void trojan_draw_sprites( struct osd_bitmap *bitmap ){
  403.     const struct rectangle *clip = &Machine->drv->visible_area;
  404.     int offs;
  405.  
  406.     for( offs = spriteram_size - 4;offs >= 0;offs -= 4 ){
  407.         int code = spriteram[offs];
  408.         int attrib = spriteram[offs + 1];
  409.         /*
  410.             0x80 Sprite code MSB
  411.             0x40 Sprite code MSB
  412.             0x20 Sprite code MSB
  413.             0x10 X flip
  414.             0x08 colour
  415.             0x04 colour
  416.             0x02 colour
  417.             0x01 X MSB
  418.         */
  419.         int sy = spriteram[offs + 2];
  420.         int sx = spriteram[offs + 3] - 0x100 * (attrib & 0x01);
  421.         if( sx && sy ){
  422.             int flipx = attrib & 0x10;
  423.             int flipy = 1;
  424.  
  425.             if( trojan_vh_type ){ /* avengers */
  426.                 flipy = !flipx;
  427.                 flipx = 0;
  428.             }
  429.  
  430.             if( attrib&0x40 ) code += 256;
  431.             if( attrib&0x80 ) code += 256*4;
  432.             if( attrib&0x20 ) code += 256*2;
  433.  
  434.             drawgfx( bitmap,Machine->gfx[2],
  435.                 code,
  436.                 (attrib & 0x0e) >> 1, /* color */
  437.                 flipx, flipy,
  438.                 sx,sy,
  439.                 clip,TRANSPARENCY_PEN,15);
  440.         }
  441.     }
  442. }
  443.  
  444. void trojan_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  445. {
  446.     int offs, sx, sy, scrollx, scrolly;
  447.     int offsy, offsx;
  448.  
  449.  
  450.     if (palette_recalc())
  451.     {
  452.         memset(dirtybuffer2,1,lwings_backgroundram_size);
  453.         memset(dirtybuffer4,1,lwings_backgroundram_size);
  454.     }
  455.  
  456.  
  457.         {
  458.               static int oldoffsy=0xffff;
  459.               static int oldoffsx=0xffff;
  460.  
  461.               scrollx = (trojan_bk_scrollx[0]);
  462.               scrolly = (trojan_bk_scrolly[0]);
  463.  
  464.               offsy = 0x20 * scrolly;
  465.               offsx = (scrollx >> 4);
  466.               scrollx = -(scrollx & 0x0f);
  467.               scrolly = 0; /* Y doesn't scroll ??? */
  468.               if (oldoffsy != offsy || oldoffsx != offsx)
  469.               {
  470.                   unsigned char *p=memory_region(REGION_GFX5);
  471.                   oldoffsx=offsx;
  472.                   oldoffsy=offsy;
  473.  
  474.                   for (sy=0; sy < 0x11; sy++)
  475.                   {
  476.                       offsy &= 0x7fff;
  477.                       for (sx=0; sx<0x11; sx++)
  478.                       {
  479.                           int code, colour;
  480.                           int offset=offsy + ((2*(offsx+sx)) & 0x3f);
  481.                           code = *(p+offset);
  482.                           colour = *(p+offset+1);
  483.                           drawgfx(tmpbitmap3, Machine->gfx[3],
  484.                                    code+((colour&0x80)<<1),
  485.                                    colour & 0x07,
  486.                                    colour&0x10,
  487.                                    colour&0x20,
  488.                                    16 * sx,16 * sy,
  489.                                    0,TRANSPARENCY_NONE,0);
  490.                       }
  491.                       offsy += 0x800;
  492.                   }
  493.               }
  494.               copyscrollbitmap(bitmap,tmpbitmap3,1,&scrollx,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  495.         }
  496.  
  497.         scrollx = (trojan_scrollx[0] + 256 * trojan_scrollx[1]);
  498.         scrolly = (trojan_scrolly[0] + 256 * trojan_scrolly[1]);
  499.  
  500.         trojan_render_foreground( bitmap, scrollx, scrolly, 0 );
  501.  
  502.     trojan_draw_sprites( bitmap );
  503.     trojan_render_foreground( bitmap, scrollx, scrolly, 1 );
  504.  
  505.     /* draw the frontmost playfield. They are characters, but draw them as sprites */
  506.     for (offs = videoram_size - 1;offs >= 0;offs--){
  507.         sx = offs % 32;
  508.         sy = offs / 32;
  509.         drawgfx(bitmap,Machine->gfx[0],
  510.                 videoram[offs] + 4 * (colorram[offs] & 0xc0),
  511.                 colorram[offs] & 0x0f,
  512.                 colorram[offs] & 0x10,colorram[offs] & 0x20,
  513.                 8*sx,8*sy,
  514.                 &Machine->drv->visible_area,TRANSPARENCY_PEN,3);
  515.     }
  516. }
  517.